package com.hulman.oms.web;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.hulman.oms.bean.*;
import com.hulman.oms.service.DeviceService;
import com.hulman.oms.service.DeviceSystemService;
import com.hulman.oms.service.LocationService;
import com.hulman.oms.service.TunnelService;
import com.hulman.oms.util.NumberUtil;
import com.hulman.oms.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Author: maxwellens
 */
@RestController
public class DeviceController
{
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private TunnelService tunnelService;
    @Autowired
    private DeviceSystemService deviceSystemService;
    @Autowired
    private HttpServletResponse response;

    @GetMapping("/devices/{id}")
    public Result findDeviceById(@PathVariable Integer id)
    {
        Device device = deviceService.findDeviceById(id);
        return new Result(device);
    }

    /**
     * 老接口
     * @param code
     * @return
     */
    @GetMapping("/devices/code/{code}")
    public Result findDeviceByCode(@PathVariable String code)
    {
        Device device = deviceService.findDeviceByCode(code);
        return new Result(device);
    }

    /**
     * 新接口
     * @param code
     * @return
     */
    @GetMapping("/devices/code")
    public Result findDeviceByCode1(String code)
    {
        Device device = deviceService.findDeviceByCode(code);
        return new Result(device);
    }

    @GetMapping("/devices/iot-code/{iotCode}")
    public Result findDeviceByIotCode(@PathVariable String iotCode)
    {
        Device device = deviceService.findDeviceByIotCode(iotCode);
        return new Result(device);
    }

    @GetMapping("/devices/select")
    public Result findDeviceByName(String name)
    {
        Device device = deviceService.findDeviceByName(name);
        return new Result(device);
    }

    @GetMapping("/devices")
    public Result findDevices(Integer page, Integer limit, Integer tunnelId, String name, String code, String system, String type, Integer isIot, Integer state, String no, String brand, String model, String spec, String productRange)
    {
        Map<String, Object> map = new HashMap<>();
        map.put("page", page);
        map.put("limit", limit);
        map.put("tunnelId", tunnelId);
        map.put("name", name);
        map.put("code", code);
        map.put("system", system);
        map.put("type", type);
        map.put("isIot", isIot);
        map.put("state", state);
        map.put("no", no);
        map.put("brand", brand);
        map.put("model", model);
        map.put("spec", spec);
        if (!StringUtil.isEmpty(productRange))
        {
            String[] dates = productRange.split(" - ");
            map.put("startDate", dates[0]);
            map.put("endDate", dates[1]);
        }
        return deviceService.findDevicesResult(map);
    }

    @RequestMapping("/devices/index")
    public Result findDevicesIndex(String name, String tunnelIds)
    {
        Map<String, Object> condition = new HashMap<>();
        condition.put("name", name);
        if (!StringUtil.isEmpty(tunnelIds))
        {
            condition.put("tunnelIds", tunnelIds.split(","));
        }
        List<Device> devices = deviceService.findDevices(condition);
        Map<String, List<String>> map = new HashMap<>();
        //通讯录格式处理
        for (Device device : devices)
        {
            //String letter = StringUtil.getPinyinFirstLetters(device.getName().substring(0, 1));
            String letter = device.getType();
            if (!map.containsKey(letter))
            {
                map.put(letter, new ArrayList<>());
            }
            map.get(letter).add(device.getName());
        }
        //对字母进行排序
        Object[] keys = map.keySet().toArray();
        Arrays.sort(keys);
        List<Object> result = new ArrayList<>();
        for (Object key : keys)
        {
            Map<String, Object> item = new HashMap<>();
            item.put("letter", key);
            item.put("data", map.get(key));
            result.add(item);
        }
        return new Result(result);
    }

    @RequestMapping("/devices/tree")
    public Result findDevicesTree()
    {
        List<TreeNode> data = new ArrayList<>();
        int id = 1;
        List<Tunnel> tunnels = tunnelService.findAllTunnels();
        List<DeviceSystem> systems = deviceSystemService.findDeviceSystems();
        for (Tunnel tunnel : tunnels)
        {
            TreeNode tunnelNode = new TreeNode();
            tunnelNode.setId(id++);
            tunnelNode.setTitle(tunnel.getName());
            for (DeviceSystem deviceSystem : systems)
            {
                TreeNode systemNode = new TreeNode();
                systemNode.setId(id++);
                systemNode.setTitle(deviceSystem.getName());
                List<Device> devices = deviceService.findDevicesByTunnelIdAndSystem(tunnel.getId(), deviceSystem.getName());
                for (Device device : devices)
                {
                    TreeNode deviceNode = new TreeNode();
                    deviceNode.setId(id++);
                    deviceNode.setTitle(device.getName());
                    systemNode.add(deviceNode);
                }
                tunnelNode.add(systemNode);
            }
            data.add(tunnelNode);
        }
        return new Result(data);
    }

    @DeleteMapping("/devices/{ids}")
    public Result deleteDeviceById(@PathVariable String ids)
    {
        int[] idArrays = NumberUtil.parseIntArray(ids);
        for (Integer id : idArrays)
        {
            deviceService.deleteDeviceById(id);
        }
        return Result.SUCCESS;
    }

    @PutMapping("/devices")
    public Result saveDevice(Device device)
    {
        deviceService.saveDevice(device);
        return Result.SUCCESS;
    }

    /**
     * 通过Excel批量导入设备信息
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/devices/import")
    public Result importDevices(MultipartFile file) throws IOException
    {
        File tmp = new File(System.getProperty("java.io.tmpdir") + "/" + System.currentTimeMillis() + ".xlsx");
        file.transferTo(tmp);
        List<Device> devices = EasyExcel.read(tmp).head(Device.class).sheet(0).doReadSync();
        List<Accessory> accessories = EasyExcel.read(tmp).head(Accessory.class).sheet(1).doReadSync();
        List<IotDevice> iotDevices = EasyExcel.read(tmp).head(IotDevice.class).sheet(2).doReadSync();
        deviceService.importDevices(devices, accessories, iotDevices);
        return Result.SUCCESS;
    }

    /**
     * 导出设备列表
     *
     * @throws IOException
     */
    @GetMapping("/devices/export")
    public void exportDevices(Integer tunnelId, String name, String code, String system, String type, Integer isIot) throws IOException
    {
        String fileName = "设备清单.xlsx";
        response.setContentType("application/octet-stream;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        Map<String, Object> map = new HashMap<>();
        map.put("tunnelId", tunnelId);
        map.put("name", name);
        map.put("code", code);
        map.put("system", system);
        map.put("type", type);
        map.put("isIot", isIot);
        List<Device> devices = deviceService.findDevices(map);
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet sheet0 = EasyExcel.writerSheet(0, "设备").head(Device.class).build();
        excelWriter.write(devices, sheet0);
        excelWriter.finish();
    }

}
